Skip to content

larryv/vimfiles

Repository files navigation

vimfiles

This is my Vim configuration. It used to be worse.

It aims to be compatible with a wide range of Vim versions (back to Vim 7.2 with the "tiny" feature set), providing reasonable fallback behavior whenever functionality is unavailable.

Here begins a series of notes to myself.

Installation

A Unix-like operating system and Bourne-adjacent shell are assumed. Error-checking is omitted for brevity.

  1. Clone this repository at $HOME/.vim, which shouldn't exist yet. If it does, delete it or move it somewhere else.

    • Git 1.7.4.1 and later:

      git clone --recurse-submodules https://github.com/larryv/vimfiles.git ~/.vim
    • Git 1.6.5 and later:

      git clone --recursive https://github.com/larryv/vimfiles.git ~/.vim
    • Otherwise:

      git clone https://github.com/larryv/vimfiles.git ~/.vim \
          && cd ~/.vim \
          && git submodule update --init --recursive

    Alternately, clone it somewhere else and create $HOME/.vim as a link to it.

    git clone --recurse-submodules https://github.com/larryv/vimfiles.git /somewhere/else \
        && ln -s /somewhere/else ~/.vim
  2. Certain uncommon setups require additional steps.

    • If using Vim 7.2 or earlier or 7.3 without patch 1178, create $HOME/.vimrc and $HOME/.gvimrc as links to .vim/vimrc and .vim/gvimrc.

      ln -s .vim/vimrc ~/.vimrc
      ln -s .vim/gvimrc ~/.gvimrc
    • If using an +eval-less Vim:

      • Make sure $HOME/.vimrc.local and $HOME/.gvimrc.local exist, even if one or both are empty. This suppresses a harmless but vexing "Can't open file" message.

        touch ~/.vimrc.local ~/.gvimrc.local
      • If using Vim 7.1 or later or 7.0 with patches 234 and 235, reenable modelines in $HOME/.vimrc.local. They are disabled by default to mitigate CVE-2007-2438.

        set modeline&
        set modelines&

Customization

(Obviously the working copy can be modified arbitrarily, but the customizations described here are not tracked by Git.)

To add settings that are not suitable for the repository, create and populate $HOME/.vimrc.local and $HOME/.gvimrc.local. These are sourced at or near the ends of $HOME/.vim/vimrc and $HOME/.vim/gvimrc, so they can build on or override settings from those files. (See vimrc.local.sample and gvimrc.local.sample.)

To use packages that are not suitable for the repository, place them anywhere in $HOME/.vim/pack other than versioned.

Development

Look to the Google Vimscript Guide. Although it's mostly about writing plugins, it contains some recommendations that are useful here, especially under "Portability", "Variables", "Strings", "Settings", and "Functions".

Maintain portability across Vim versions and feature sets; the baseline is Vim 7.2 with the "tiny" feature set. The most disruptive requirement is probably accommodating a lack of +eval (outside of plugins, which are not used at all in that case).

  • Establish portable defaults first, then override them later if desired. This can be an adequate +eval-less replacement for if/else or try/catch, as long as the overriding code fails without side effects or is conditionalized in another way.

    set listchars=tab:>-          " Works in 7.2.
    silent set listchars=tab:-->  " Fails without patch 8.1.0795.
    set showbreak=>>>   " vimrc: Enable this by default.
    set showbreak&      " gvimrc: Reset it in the GUI.
  • Use silent! to run most commands that don't need +eval, do have other requirements, and fail loudly if those are not met.

    silent! syntax enable         " Needs +syntax.
    silent! set formatoptions+=j  " Needs patch 7.3.541.
  • Use if to protect code that requires +eval; without +eval, everything between if and endif is ignored, including the condition. Use if 1 unless there are more conditions to impose.

    " Calling functions requires +eval.  We also need +autocmd, so check
    " for that while I'm at it.
    if has('autocmd')
        autocmd EncodingChanged * call s:EncodingChangedHandler()
    endif

    Also use it to conditionalize code that doesn't fail cleanly on its own. Since this code will never run without +eval, make sure the defaults are reasonable.

    set softtabstop=4
    if v:version > 703 || (v:version == 703 && has('patch693'))
        " This throws an error if -1 is invalid but sets 'softtabstop'
        " to 0 without warning.  Rude!
        set softtabstop=-1
    endif
  • Given two equivalent constructs, prefer the one that works with older versions of Vim. For example, has('patch-8.1.0759') is nice but requires patch 7.4.237; do it the long way instead.

    if v:version > 801 || (v:version == 801 && has('patch0759'))
        let s:tmp .= ",tab:\xe2\x8e\xaf\xe2\x8e\xaf\xe2\x86\x92"
    else

Legal

To the extent possible under law, the author has dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is published from the United States of America and distributed without any warranty.